home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
-
- #include "parse.h"
- #include <gl.h>
- #include <device.h>
- #include <math.h>
- #include <stream.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include "generic.h"
- #include "gizmo.h"
- #include <getopt.h>
- #include <unistd.h>
-
- reservedword currentlinetype = _segment;
- void handleredraw();
- void initshowcaseui();
- void setselect();
-
- float pbsize;
-
- float fxmin = -1.0, fxmax = 1.0;
- float fymin = -1.0, fymax = 1.0;
- extern long xorg, yorg, xsize, ysize;
- extern long linecount, layerset;
-
- primitive *plist = 0, *plisttail = 0;
- primitive *pselected = 0;
-
- /* primssame() determines whether the primitives are the same --
- * same type, same constraints, ... This routine only does a
- * correct check on primitives entered via the buttons.
- */
-
- long primssame(primitive *p, primitive *q)
- {
- primitive *p1, *p2, *p3, *q1, *q2, *q3;
-
- if (p->ptype == _comment || p->ptype == _text ||
- p->ptype == _length) return 0;
- constrainttype ct = p->c.type;
- if (ct != q->c.type) return 0;
- switch (ct) {
- case VERTFREE:
- case VERTONLINE:
- case VERTONCIRCLE:
- case VERTONCONIC:
- return 0;
- case VERTLINELINE:
- case VERTVERTVERTMID:
- case LINEVERTVERT:
- if ((p->c.p1 != q->c.p1 || p->c.p2 != q->c.p2) &&
- (p->c.p1 != q->c.p2 || p->c.p2 != q->c.p1)) return 0;
- break;
- case VERTLINECIRC1:
- case VERTLINECIRC2:
- case VERTCIRCCIRC1:
- case VERTCIRCCIRC2:
- case LINEVERTLINEPAR:
- case LINEVERTLINEPERP:
- case LINEVERTCIRC1:
- case LINEVERTCIRC2:
- case LINECIRCCIRCEXT1:
- case LINECIRCCIRCEXT2:
- case CIRCVERTVERT:
- if (p->c.p1 != q->c.p1 || p->c.p2 != q->c.p2) return 0;
- break;
- case CIRCVERTVERTVERT:
- p1 = p->c.p1, p2 = p->c.p2, p3 = p->c.p3;
- q1 = q->c.p1, q2 = q->c.p2, q3 = q->c.p3;
- if (!((p1 == q1 && p2 == q2 && p3 == q3) ||
- (p1 == q2 && p2 == q1 && p3 == q3) ||
- (p1 == q1 && p2 == q3 && p3 == q2) ||
- (p1 == q3 && p2 == q2 && p3 == q1) ||
- (p1 == q2 && p2 == q3 && p3 == q1) ||
- (p1 == q3 && p2 == q1 && p3 == q2))) return 0;
- break;
- default:
- if (p->c.p1 != q->c.p1 || p->c.p2 != q->c.p2 ||
- p->c.p3 != q->c.p3 || p->c.p4 != q->c.p4 ||
- p->c.p5 != q->c.p5) return 0;
- break;
- }
- if (p->Color != q->Color || p->layers != q->layers) return 0;
- return 1;
- }
-
- void addprimitive(primitive *p)
- {
- for (primitive *p1 = plist; p1; p1 = p1->next) {
- if (primssame(p, p1)) {
- delete p;
- removeentry(restable, p->st->symbol);
- message("Duplicate primitive -- not added", 0, 0, 0);
- setselect();
- return;
- }
- }
- setdirtyfile();
- if (plisttail) {
- plisttail->next = p;
- plisttail = p;
- } else
- plist = plisttail = p;
- }
-
- void clearplist()
- {
- while (plist) {
- primitive *p = plist->next;
- delete plist;
- plist = plist->next;
- }
- plisttail = pselected = 0;
- linecount = 1;
- }
-
- void zoomworld(float zoom)
- {
- vertex *v;
-
- for (primitive *p = plist; p; p = p->next) {
- switch (p->c.type) {
- case VERTFREE:
- case VERTONLINE:
- case VERTONCIRCLE:
- case VERTONCONIC:
- v = (vertex *)p;
- v->xw *= zoom;
- v->yw *= zoom;
- break;
- default:
- break;
- }
- p->satisfied = 0;
- }
- }
-
- void moveworld(long dx, long dy)
- {
- vertex *v;
-
- for (primitive *p = plist; p; p = p->next) {
- switch (p->c.type) {
- case VERTFREE:
- case VERTONLINE:
- case VERTONCIRCLE:
- case VERTONCONIC:
- v = (vertex *)p;
- v->xw += .01*dx;
- v->yw += .01*dy;
- break;
- default:
- break;
- }
- p->satisfied = 0;
- }
- }
-
- static long appliedconstraint;
-
- void checkconstraint(primitive *p)
- {
- line *l, *l1;
- vertex *v, *v1, *v2;
- circle *c;
- bezier *b;
- conic *con, *cnc;
- length *len1, *len2, *len3;
- float dx, dy, radd, rad;
-
- if (p->c.type != VERTFREE && p->c.p1 == 0) {
- p->satisfied = 1;
- return;
- }
- switch(p->c.type) {
- case VERTFREE:
- break;
- case LINEVERTVERT:
- l = (line *)p;
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0)
- return;
- l->v1 = *(vertex *)p->c.p1;
- l->v2 = *(vertex *)p->c.p2;
- homogenizeline(l);
- break;
- case VERTLINELINE:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0)
- return;
- vertonlineline((vertex *)p, (line *)p->c.p1, (line *)p->c.p2);
- break;
- case VERTONLINE:
- if (p->c.p1->satisfied == 0)
- return;
- v = (vertex *)p;
- l = (line *)p->c.p1;
- v->projecttoline(l);
- break;
- case VERTONCONIC:
- if (p->c.p1->satisfied == 0)
- return;
- v = (vertex *)p;
- con = (conic *)p->c.p1;
- projecttoconic(v, con);
- break;
- case VERTLINEVERTMIRROR:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0)
- return;
- vlvmirror((vertex *)p);
- break;
- case VERTONCIRCLE:
- if (p->c.p1->satisfied == 0)
- return;
- v = (vertex *)p;
- c = (circle *)p->c.p1;
- dx = v->xw - c->center.xw;
- dy = v->yw - c->center.yw;
- radd = c->radius/sqrt(dx*dx + dy*dy);
- v->xw = c->center.xw + dx*radd;
- v->yw = c->center.yw + dy*radd;
- break;
- case VERTCIRCCENTER:
- if (p->c.p1->satisfied == 0)
- return;
- v = (vertex *)p;
- c = (circle *)p->c.p1;
- v->xw = c->center.xw;
- v->yw = c->center.yw;
- break;
- case VERTVERTVERTMID:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0)
- return;
- v = (vertex *)p;
- v1 = (vertex *)p->c.p1;
- v2 = (vertex *)p->c.p2;
- if (v1->w == 0.0) { v->w = 0; v->xw = v1->xw; v->yw = v1->yw; break; }
- if (v2->w == 0.0) { v->w = 0; v->xw = v2->xw; v->yw = v2->yw; break; }
- v->xw = (v1->xw + v2->xw)/2.0;
- v->yw = (v1->yw + v2->yw)/2.0;
- v->w = 1.0;
- break;
- case LINEVERTLINEPERP:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0)
- return;
- l = (line *)p;
- v = (vertex *)p->c.p1;
- l1 = (line *)p->c.p2;
- l->XW = -l1->YW; l->YW = l1->XW;
- l->W = l1->YW*v->xw - l1->XW*v->yw;
- l->v1 = *v;
- l->v2.xw = -l->YW; l->v2.yw = l->XW; l->v2.w = 0.0;
- break;
- case LINEVERTLINEPAR:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0)
- return;
- l = (line *)p;
- v = (vertex *)p->c.p1;
- l1 = (line *)p->c.p2;
- l->XW = l1->XW; l->YW = l1->YW;
- l->W = -(l->XW*v->xw + l->YW*v->yw);
- l->v1 = *v;
- l->v2.xw = -l->YW; l->v2.yw = l->XW; l->v2.w = 0.0;
- break;
- case CIRCVERTVERT:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0)
- return;
- v = (vertex *)p->c.p1;
- v1 = (vertex *)p->c.p2;
- rad = vvdist(v, v1);
- c = (circle *)p;
- c->center.xw = v->xw;
- c->center.yw = v->yw;
- c->center.w = v->w;
- c->radius = rad;
- break;
- case VERTLINECIRC1:
- case VERTLINECIRC2:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0)
- return;
- l = (line *)p->c.p1;
- v1 = (vertex *)&l->v1;
- v2 = (vertex *)&l->v2;
- c = (circle *)p->c.p2;
- v = (vertex *)p;
- solvevlc(l, c, v, (p->c.type == VERTLINECIRC1) ? 1 : 2);
- break;
- case VERTLINECONIC1:
- case VERTLINECONIC2:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0)
- return;
- vert_lineconic((vertex *)p);
- break;
- case LINEVERTCIRC1:
- case LINEVERTCIRC2:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0)
- return;
- line_vertcircletan((line *)p);
- break;
- case LINECIRCCIRCEXT1:
- case LINECIRCCIRCEXT2:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0)
- return;
- line_circcircleext((line *)p);
- break;
- case LINECIRCCIRCINT1:
- case LINECIRCCIRCINT2:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0)
- return;
- line_circcircleint((line *)p);
- break;
- case VERTCIRCCIRC1:
- case VERTCIRCCIRC2:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0)
- return;
- vert_circcircle((vertex *)p);
- break;
- case CIRCLINELINELINE1:
- case CIRCLINELINELINE2:
- case CIRCLINELINELINE3:
- case CIRCLINELINELINE4:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0 ||
- p->c.p3->satisfied == 0)
- return;
- circle_lll((circle *)p);
- break;
- case CIRCVERTVERTVERT:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0 ||
- p->c.p3->satisfied == 0)
- return;
- circle_vvv((circle *)p);
- break;
- case CIRCCIRCCIRCINV:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0)
- return;
- circle_ccinvert((circle *)p);
- break;
- case VERTCIRCVERTINV:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0)
- return;
- v_vcinvert((vertex *)p);
- break;
- case CIRCLINECIRCINV:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0)
- return;
- circle_linecinvert((circle *)p);
- break;
- case BEZVERTVERTVERTVERT:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0 ||
- p->c.p3->satisfied == 0 || p->c.p4->satisfied == 0)
- return;
- b = (bezier *)p;
- b->v1 = *(vertex *)p->c.p1;
- b->v2 = *(vertex *)p->c.p2;
- b->v3 = *(vertex *)p->c.p3;
- b->v4 = *(vertex *)p->c.p4;
- break;
- case RATIOVERTVERTVERT:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0 ||
- p->c.p3->satisfied == 0)
- return;
- ratio_vvv((length *)p);
- break;
- case VERTVERTVERTRATIO:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0 ||
- p->c.p3->satisfied == 0)
- return;
- v_vvratio((vertex *)p);
- break;
- case LENVERTVERT:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0)
- return;
- v1 = (vertex *)p->c.p1;
- v2 = (vertex *)p->c.p2;
- len1 = (length *)p;
- len1->value = vvdist(v1, v2);
- break;
- case CIRCVERTLEN:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0)
- return;
- v = (vertex *)p->c.p1;
- len1 = (length *)p->c.p2;
- c = (circle *)p;
- c->center.xw = v->xw;
- c->center.yw = v->yw;
- c->center.w = v->w;
- c->radius = len1->value;
- break;
- case LENPLUSLENLEN:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0)
- return;
- len1 = (length *)p->c.p1;
- len2 = (length *)p->c.p2;
- len3 = (length *)p;
- len3->value = len1->value + len2->value;
- break;
- case LENMINUSLENLEN:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0)
- return;
- len1 = (length *)p->c.p1;
- len2 = (length *)p->c.p2;
- len3 = (length *)p;
- len3->value = len1->value - len2->value;
- break;
- case LENTIMESLENLEN:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0)
- return;
- len1 = (length *)p->c.p1;
- len2 = (length *)p->c.p2;
- len3 = (length *)p;
- len3->value = len1->value * len2->value;
- break;
- case LENDIVLENLEN:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0)
- return;
- len1 = (length *)p->c.p1;
- len2 = (length *)p->c.p2;
- len3 = (length *)p;
- if (len2->value != 0.0)
- len3->value = len1->value / len2->value;
- else
- len3->value = 1.0e30;
- break;
- case LENANGLE:
- if (p->c.p1->satisfied == 0) return;
- ((length *)p)->value = ((length *)p->c.p1)->value;
- break;
- case ANGLEVERTVERTVERT:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0 ||
- p->c.p3->satisfied == 0)
- return;
- a_vvv((length *)p);
- break;
- case VERTANGLEVERTVERT:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0 ||
- p->c.p3->satisfied == 0)
- return;
- v_avv((vertex *)p);
- break;
- case CONICFIVEVERT:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0 ||
- p->c.p3->satisfied == 0 || p->c.p4->satisfied == 0 ||
- p->c.p5->satisfied == 0)
- return;
- cnc = (conic *)p;
- conic_vvvvv(cnc);
- break;
- case CONICFIVELINE:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0 ||
- p->c.p3->satisfied == 0 || p->c.p4->satisfied == 0 ||
- p->c.p5->satisfied == 0)
- return;
- cnc = (conic *)p;
- conic_lllll(cnc);
- break;
- case LINETANGENTCONIC1:
- case LINETANGENTCONIC2:
- if (p->c.p1->satisfied == 0 || p->c.p2->satisfied == 0)
- return;
- l = (line *)p;
- linetangenttoconic(l);
- break;
- }
- p->satisfied = 1;
- appliedconstraint = 1;
- }
-
- void checkconstraints()
- {
- long hit;
-
- if (pselected) {
- pselected->satisfied = 0;
- do {
- hit = 0;
- for (primitive *p = plist; p; p = p->next) {
- if (p->satisfied && p->c.p1 && p->c.p1->satisfied == 0) {
- hit = 1;
- p->satisfied = 0;
- } else
- if (p->satisfied && p->c.p2 && p->c.p2->satisfied == 0) {
- hit = 1;
- p->satisfied = 0;
- } else
- if (p->satisfied && p->c.p3 && p->c.p3->satisfied == 0) {
- hit = 1;
- p->satisfied = 0;
- } else
- if (p->satisfied && p->c.p4 && p->c.p4->satisfied == 0) {
- hit = 1;
- p->satisfied = 0;
- }
- if (p->satisfied && p->c.p5 && p->c.p5->satisfied == 0) {
- hit = 1;
- p->satisfied = 0;
- }
- }
- } while (hit == 1);
- }
- // for (primitive *p = plist; p; p = p->next)
- // p->satisfied = 0;
- do {
- appliedconstraint = 0;
- for (primitive *p = plist; p; p = p->next)
- if (p->satisfied == 0) checkconstraint(p);
- } while (appliedconstraint == 1);
- for (primitive *p = plist; p; p = p->next)
- if (p->satisfied == 0) {
- displaymessage("Wacko constraints");
- }
- }
-
- long isconstrained(primitive *pp)
- {
- for (primitive *p = plist; p; p = p->next) {
- if (p->c.p1 == pp || p->c.p2 == pp || p->c.p3 == pp)
- return 1;
- }
- return 0;
- }
-
- void deleteprimitive(primitive *pp)
- {
- if (isconstrained(pp)) {
- displaymessage("Sorry, it's constrained");
- return;
- }
- if (pp == pselected) pselected = 0;
- if (pp == plist) {
- plist = plist->next;
- if (plist == 0) plisttail = 0;
- } else for (primitive *p = plist; p; p = p->next) {
- if (p->next == pp) {
- p->next = pp->next;
- if (pp == plisttail) plisttail = p;
- }
- }
- /* stuff to free? XXX */
- removeentry(restable, pp->st->symbol);
- delete pp;
- }
-
- void selectvertex(float fx, float fy)
- {
- vertex *v;
- short x, y;
-
- if (v = hitvertex(fx, fy)) {
- pselected = v;
- drawmode(PUPDRAW); color(0); clear(); drawmode(NORMALDRAW);
- while (getbutton(LEFTMOUSE)) {
- x = (short)getvaluator(MOUSEX);
- y = (short)getvaluator(MOUSEY);
- getpoint(&fx, &fy, x, y);
- if (fx > .999*fxmax) fx = .999*fxmax;
- if (fx < -.999*fxmax) fx = -.999*fxmax;
- if (fy > .999*fymax) fy = .999*fymax;
- if (fy < -.999*fymax) fy = -.999*fymax;
- v->xw = fx; v->yw = fy; v->w = 1.0;
- v->satisfied = 0;
- drawgeom();
- }
- drawmode(PUPDRAW); color(0); clear(); drawmode(NORMALDRAW);
- } else {
- pselected = hitprimitive(fx, fy);
- }
- while (getbutton(LEFTMOUSE))
- ; // do nothing -- just wait.
- qreset();
- }
-
- main(int argc, char **argv)
- {
- int ch;
-
- while ((ch = getopt(argc, argv, "fv")) != -1)
- switch (ch) {
- case 'f': /* foreground */
- foreground_flag = 1;
- break;
- case 'v': /* view-only */
- VIEW_ONLY = view_only = 1;
- break;
- case '?':
- fprintf(stderr, "usage: %s [-fv] [file]\n", argv[0]);
- exit(-1);
- }
- MAKE_BACKUPS = MAKE_CHECKPOINTS = 0; /* OPTIONAL */
- initialize();
- inittables();
- if (argc - optind >= 1)
- doopen(argv[optind]);
- else if (VIEW_ONLY) {
- fprintf(stderr, "You must name a file in view-only mode\n");
- exit(-1);
- }
- /*initsignal(); /* OPTIONAL */
- /*opengizmo(GIZMO_MASTER); /* OPTIONAL */
- makewintitle();
- getwindowinfo();
- recalcsizes();
- makepulldown(); /* OPTIONAL - must follow winopen */
- mainloop();
- }
-
- vertex *hitvertex(float fx, float fy)
- {
- vertex *v;
-
- for (primitive *p = plist; p; p = p->next) {
- if (p->ptype == _vertex && (p->layers&layerset)) {
- v = (vertex *)p;
- if (v->hitvertex(fx, fy)) return (vertex *)p;
- }
- }
- return (vertex *)0;
- }
-
- line *hitline(float fx, float fy)
- {
- line *l;
-
- for (primitive *p = plist; p; p = p->next) {
- if (p->ptype == _line) {
- l = (line *)p;
- if (l->hitline(fx, fy)) return (line *)p;
- }
- }
- return (line *)0;
- }
-
- line *hitanotherline(float fx, float fy, primitive *ll)
- {
- line *l;
-
- for (primitive *p = plist; p; p = p->next) {
- if (p->ptype == _line && (p != ll)) {
- l = (line *)p;
- if (l->hitline(fx, fy)) return (line *)p;
- }
- }
- return (line *)0;
- }
-
- circle *hitcircle(float fx, float fy)
- {
- circle *c;
-
- for (primitive *p = plist; p; p = p->next) {
- if (p->ptype == _circle) {
- c = (circle *)p;
- if (c->hitcircle(fx, fy)) return (circle *)p;
- }
- }
- return (circle *)0;
- }
-
- circle *hitanothercircle(float fx, float fy, primitive *cc)
- {
- circle *c;
-
- for (primitive *p = plist; p; p = p->next) {
- if (p->ptype == _circle && (p != cc)) {
- c = (circle *)p;
- if (c->hitcircle(fx, fy)) return (circle *)p;
- }
- }
- return (circle *)0;
- }
-
- primitive *hitprimitive(float fx, float fy)
- {
- line *l;
- vertex *v;
- circle *c;
- bezier *bez;
- conic *con;
-
- for (primitive *p = plist; p; p = p->next) {
- if (layerset & p->layers) switch (p->ptype) {
- case _line:
- l = (line *)p;
- if (l->hitline(fx, fy)) return p;
- break;
- case _vertex:
- v = (vertex *)p;
- if (v->hitvertex(fx, fy)) return p;
- break;
- case _circle:
- c = (circle *)p;
- if (c->hitcircle(fx, fy)) return p;
- break;
- case _bezier:
- bez = (bezier *)p;
- if (bez->hitbezier(fx, fy)) return p;
- break;
- case _conic:
- con = (conic *)p;
- if (con->hitconic(fx, fy)) return p;
- break;
- }
- }
- return (primitive *)0;
- }
-
- void showcomment()
- {
- long linecount = 0;
- char sysstring[60];
- mode_t omask = umask(0);
- FILE *fp = fopen("geom.com", "w");
- umask(omask);
- if (fp == 0) {
- displaymessage("Couldn't open geom.com");
- return;
- }
- for (primitive *p = plist; p; p = p->next)
- if (p->ptype == _text) {
- fprintf(fp, "%s\n", ((comment *)p)->str);
- linecount++;
- }
- if (linecount == 0) {
- fprintf(fp, "The clown who wrote this example neglected to\n");
- fprintf(fp, "provide any documentation.\n");
- linecount = 2;
- }
- fprintf(fp, "\nTo exit, hold down either alt-key and press 'q'\n");
- linecount += 2;
- fclose(fp);
- long zipsize = 16*linecount;
- if (zipsize < 250) zipsize = 250;
- sprintf(sysstring, "jot -v -F8 -p200,900,%d,700 geom.com", 680-zipsize);
- system(sysstring);
- }
-
- long smearflag = 0;
-
- void drawgeom()
- {
- float ym = 0.0;
- float yinfo = fymin + 8*2.3*pbsize;
- vertex *v;
- line *l;
- circle *c;
- conic *con;
- bezier *b;
- length *ll;
- text *tt;
-
- checkconstraints();
- font(0); /* XXX shouldn't need this!!! */
- pushviewport();
- pushmatrix();
- viewport(0, (short)(xsize-UIWIDTH-1), 0, (short)(ysize-PULLDOWNHEIGHT-1));
- ortho2(fxmin, fxmax, fymin, fymax);
- initscreen();
- for (primitive *p = plist; p; p = p->next)
- if (layerset & p->layers) switch (p->ptype) {
- case _vertex:
- v = (vertex *)p;
- v->draw();
- if (smearflag && v->Color == SMEAR)
- v->PostScript(stdout);
- break;
- case _line:
- l = (line *)p;
- l->draw();
- if (smearflag && l->Color == SMEAR)
- l->PostScript(stdout);
- break;
- case _circle:
- c = (circle *)p;
- c->draw();
- if (smearflag && c->Color == SMEAR)
- c->PostScript(stdout);
- break;
- case _conic:
- con = (conic *)p;
- con->draw();
- if (smearflag && con->Color == SMEAR)
- con->PostScript(stdout);
- break;
- case _bezier:
- b = (bezier *)p;
- b->draw();
- if (smearflag && b->Color == SMEAR)
- b->PostScript(stdout);
- break;
- case _length:
- ll = (length *)p;
- if (ll->name[0] == 0) break;
- cmov2(-.99, ym); ym -= 2.3*pbsize;
- ll->draw();
- if (smearflag && ll->Color == SMEAR)
- ll->PostScript(stdout);
- break;
- case _text:
- tt = (text *)p;
- //if (tt->str[0] == 0) break;
- cmov2(-.99, yinfo); yinfo -= 2.3*pbsize;
- tt->draw();
- break;
- }
- drawpulldown();
- swapbuffers();
- popviewport();
- popmatrix();
- }
-
- long vnumber = 1;
-
- void genname(primitive *p)
- {
- long i = 1;
- char *str, s[100];
-
- switch (p->ptype) {
- case _vertex: str = "v"; break;
- case _line: str = "l"; break;
- case _circle: str = "c"; break;
- case _bezier: str = "bez"; break;
- case _conic: str = "con"; break;
- }
- do {
- sprintf(s, "%s%d", str, i++);
- } while (lookup(idtable, s));
- symtableentry *st = addentry(idtable, s, p->ptype);
- st->p = p; p->st = st;
- }
-
- vertex *makevertex(float x, float y)
- {
- vertex *v = new vertex;
- genname(v);
- sprintf(v->name, "%d", vnumber++);
- v->xw = x; v->yw = y; v->w = 1.0;
- pselected = v;
- return v;
- }
-
- void initscreen()
- {
- color(BLACK);
- clear();
- color(WHITE);
- }
-
- void recalcsizes()
- {
- initshowcaseui();
- if (xsize-UIWIDTH < ysize-PULLDOWNHEIGHT) {
- fxmin = -1.0; fxmax = 1.0;
- fymax = ((float)(ysize-PULLDOWNHEIGHT))/(xsize-UIWIDTH);
- fymin = -fymax;
- pbsize = 12.0/(xsize-UIWIDTH);
- } else {
- fymin = -1.0; fymax = 1.0;
- fxmax = ((float) (xsize-UIWIDTH))/(ysize-PULLDOWNHEIGHT);
- fxmin = -fxmax;
- pbsize = 12.0/(ysize-PULLDOWNHEIGHT);
- }
- }
-
- short oldr, oldg, oldb;
- extern int gd;
-
- void initialize()
- {
- if (foreground_flag) foreground();
- prefposition(20, 755+UIWIDTH, 20, 755);
- // prefposition(20, 755+UIWIDTH, 220, 955);
- winopen("geometry");
- gd = (int)qgetfd();
- winconstraints();
- doublebuffer();
- gconfig();
- qdevice(LEFTARROWKEY); qdevice(UPARROWKEY);
- qdevice(DOWNARROWKEY); qdevice(RIGHTARROWKEY);
- qdevice(PAGEUPKEY); qdevice(PAGEDOWNKEY);
- qdevice(LEFTMOUSE);
- qdevice(MIDDLEMOUSE);
- qdevice(KEYBD);
- qdevice(MOUSEX); qdevice(MOUSEY);
- qdevice(WINQUIT); qdevice(WINSHUT);
- getmcolor(255, &oldr, &oldg, &oldb);
- mapcolor(255, 255, 255, 0);
- blink(25, 255, 0, 0, 0);
- glcompat(GLC_MQUEUERATE, GLC_COMPATRATE);
- }
-
- void restore255()
- {
- blink(0, 255, oldr, oldg, oldb);
- mapcolor(255, oldr, oldg, oldb);
- gflush();
- }
-
- void getpoint(float *x, float *y, long sx, long sy)
- {
- *x = 2.0*fxmax*(sx - xorg)/(xsize-UIWIDTH) + fxmin;
- *y = 2.0*fymax*(sy - yorg)/(ysize-PULLDOWNHEIGHT) +fymin;
- }
-
- line *linevertvert(vertex *v1, vertex *v2)
- {
- line *l = new line;
- genname(l);
- l->c.p1 = v1; l->c.p2 = v2;
- l->type = currentlinetype;
- l->c.type = LINEVERTVERT;
- pselected = l;
- return l;
- }
-
- vertex *vertvertvertmid(vertex *v1, vertex *v2)
- {
- vertex *v = new vertex;
- genname(v);
- v->c.p1 = v1; v->c.p2 = v2;
- v->c.type = VERTVERTVERTMID;
- v->type = _plus;
- pselected = v;
- return v;
- }
-
- circle *circvertvert(vertex *v1, vertex *v2)
- {
- circle *c = new circle;
- genname(c);
- c->c.p1 = v1; c->c.p2 = v2;
- c->c.type = CIRCVERTVERT;
- pselected = c;
- return c;
- }
-
- vertex *vertlineline(line *l1, line *l2)
- {
- vertex *v = new vertex;
- genname(v);
- v->c.type = VERTLINELINE;
- v->c.p1 = l1; v->c.p2 = l2;
- v->type = _plus;
- pselected = v;
- return v;
- }
-
- void verttoline(vertex *v1, line *l1)
- {
- v1->c.p1 = l1;
- v1->c.type = VERTONLINE;
- v1->type = _cross;
- }
-
- void verttocirc(vertex *v1, circle *c1)
- {
- v1->c.p1 = c1;
- v1->c.type = VERTONCIRCLE;
- v1->type = _cross;
- }
-
- line *linevertlineperp(vertex *v, line *l1)
- {
- line *l = new line;
- genname(l);
- l->c.p1 = v; l->c.p2 = l1;
- l->type = currentlinetype;
- l->c.type = LINEVERTLINEPERP;
- pselected = l;
- return l;
- }
-
- line *linevertlinepar(vertex *v, line *l1)
- {
- line *l = new line;
- genname(l);
- l->c.p1 = v; l->c.p2 = l1;
- l->type = currentlinetype;
- l->c.type = LINEVERTLINEPAR;
- pselected = l;
- return l;
- }
-
- vertex *linecirctovert1(line *l, circle *c, float fx, float fy)
- {
- vertex *v = new vertex;
- genname(v);
- v->c.type = VERTLINECIRC1;
- v->c.p1 = l; v->c.p2 = c;
- checkconstraint(v);
- float d1 = (v->xw - fx)*(v->xw - fx)+(v->yw-fy)*(v->yw-fy);
- v->c.type = VERTLINECIRC2;
- checkconstraint(v);
- float d2 = (v->xw - fx)*(v->xw - fx)+(v->yw-fy)*(v->yw-fy);
- if (d1 < d2) v->c.type = VERTLINECIRC1;
- v->type = _plus;
- pselected = v;
- return v;
- }
-
- line *vertcirctoline1(vertex *v, circle *c, float fx, float fy)
- {
- line *l = new line;
- genname(l);
- l->c.type = LINEVERTCIRC1;
- l->c.p1 = v; l->c.p2 = c;
- l->type = currentlinetype;
- checkconstraint(l);
- float d1 = (l->v1.xw - fx)*(l->v1.xw - fx)+(l->v1.yw-fy)*(l->v1.yw-fy);
- float d2 = (l->v2.xw - fx)*(l->v2.xw - fx)+(l->v2.yw-fy)*(l->v2.yw-fy);
- l->c.type = LINEVERTCIRC2;
- checkconstraint(l);
- float d3 = (l->v1.xw - fx)*(l->v1.xw - fx)+(l->v1.yw-fy)*(l->v1.yw-fy);
- float d4 = (l->v2.xw - fx)*(l->v2.xw - fx)+(l->v2.yw-fy)*(l->v2.yw-fy);
- if ((d1<d3 && d1<d4) || (d2<d3 && d2<d4)) l->c.type = LINEVERTCIRC1;
- pselected = l;
- return l;
- }
-
- line *circcirctolineext1(circle *c1, circle *c2, float fx, float fy)
- {
- line *l = new line;
- genname(l);
- l->c.type = LINECIRCCIRCEXT1;
- l->c.p1 = c1; l->c.p2 = c2;
- l->type = currentlinetype;
- checkconstraint(l);
- float d1 = (l->v1.xw - fx)*(l->v1.xw - fx)+(l->v1.yw-fy)*(l->v1.yw-fy);
- float d2 = (l->v2.xw - fx)*(l->v2.xw - fx)+(l->v2.yw-fy)*(l->v2.yw-fy);
- l->c.type = LINECIRCCIRCEXT2;
- checkconstraint(l);
- float d3 = (l->v1.xw - fx)*(l->v1.xw - fx)+(l->v1.yw-fy)*(l->v1.yw-fy);
- float d4 = (l->v2.xw - fx)*(l->v2.xw - fx)+(l->v2.yw-fy)*(l->v2.yw-fy);
- if ((d1<d3 && d1<d4) || (d2<d3 && d2<d4)) l->c.type = LINECIRCCIRCEXT1;
- pselected = l;
- return l;
- }
-
- line *circcirctolineint1(circle *c1, circle *c2, float fx, float fy)
- {
- line *l = new line;
- genname(l);
- l->c.type = LINECIRCCIRCINT1;
- l->c.p1 = c1; l->c.p2 = c2;
- l->type = currentlinetype;
- checkconstraint(l);
- float d1 = (l->v1.xw - fx)*(l->v1.xw - fx)+(l->v1.yw-fy)*(l->v1.yw-fy);
- float d2 = (l->v2.xw - fx)*(l->v2.xw - fx)+(l->v2.yw-fy)*(l->v2.yw-fy);
- l->c.type = LINECIRCCIRCINT2;
- checkconstraint(l);
- float d3 = (l->v1.xw - fx)*(l->v1.xw - fx)+(l->v1.yw-fy)*(l->v1.yw-fy);
- float d4 = (l->v2.xw - fx)*(l->v2.xw - fx)+(l->v2.yw-fy)*(l->v2.yw-fy);
- if ((d1<d3 && d1<d4) || (d2<d3 && d2<d4)) l->c.type = LINECIRCCIRCINT1;
- pselected = l;
- return l;
- }
-
- vertex *circcirctovert1(circle *c1, circle *c2, float fx, float fy)
- {
- vertex *v = new vertex;
- genname(v);
- v->c.type = VERTCIRCCIRC1;
- v->c.p1 = c1; v->c.p2 = c2;
- checkconstraint(v);
- float d1 = (v->xw - fx)*(v->xw - fx)+(v->yw-fy)*(v->yw-fy);
- v->c.type = VERTCIRCCIRC2;
- checkconstraint(v);
- float d2 = (v->xw - fx)*(v->xw - fx)+(v->yw-fy)*(v->yw-fy);
- if (d1 < d2) v->c.type = VERTCIRCCIRC1;
- v->type = _plus;
- pselected = v;
- return v;
- }
-
- vertex *circcirctovert2(circle *c1, circle *c2)
- {
- vertex *v = new vertex;
- genname(v);
- v->c.type = VERTCIRCCIRC2;
- v->c.p1 = c1; v->c.p2 = c2;
- v->type = _plus;
- pselected = v;
- return v;
- }
-
- circle *vvvtocircle(vertex *v1, vertex *v2, vertex *v3)
- {
- circle *c = new circle;
- genname(c);
- c->c.p1 = v1; c->c.p2 = v2; c->c.p3 = v3;
- c->c.type = CIRCVERTVERTVERT;
- pselected = c;
- return c;
- }
-
- conic *vvvvvtoconic(vertex *v1, vertex *v2, vertex *v3, vertex *v4, vertex *v5)
- {
- conic *c = new conic;
- genname(c);
- c->c.p1 = v1; c->c.p2 = v2; c->c.p3 = v3, c->c.p4 = v4; c->c.p5 = v5;
- c->c.type = CONICFIVEVERT;
- pselected = c;
- return c;
- }
-